﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.PowerShell;
using System.Management.Automation;
using AutocompleteDemo;

namespace AutocompleteDemo.Cmdlet
{
    [Cmdlet(VerbsCommon.New, "AutoCompletionServiceApplication", SupportsShouldProcess = true)]
    public sealed class NewAutoCompletionServiceApplication : SPNewCmdletBase<AutoCompletionServiceApplication>
    {
        #region [Fields]

        private SPIisWebServiceApplicationPoolPipeBind m_applicationPoolPipeBind;
        private SwitchParameter m_default;
        private string m_name;
        private SPIisWebServiceApplicationPool m_resolvedApplicationPool;

        #endregion

        #region [Parameters]

        [Parameter(Mandatory = true)]
        public string Name
        {
            get
            {
                return this.m_name;
            }
            set
            {
                this.m_name = value;
            }
        }

        [Parameter(Mandatory = false)]
        public SwitchParameter Default
        {
            get
            {
                return this.m_default;
            }
            set
            {
                this.m_default = value;
            }
        }

        #endregion

        [Parameter(Mandatory = true, ValueFromPipeline = true), ValidateNotNull]
        public SPIisWebServiceApplicationPoolPipeBind SPIisWebServiceApplicationPool
        {
            get
            {
                return this.m_applicationPoolPipeBind;
            }
            set
            {
                this.m_applicationPoolPipeBind = value;
            }
        }
 
        // Methods
        internal void CloneValuesTo(AutoCompletionServiceApplication applicationObject)
        {
            applicationObject.CloneValues(base.Fields);
        }

        #region [SPNewCmdletBase]

        protected override AutoCompletionServiceApplication CreateDataObject()
        {
            AutoCompletionServiceApplication applicationObject = null;

            if (base.ShouldProcess(this.Name))
            {
                // If first app, force to be default
                bool forceDefault = AutoCompletionService.Local.GetApplications().Count < 1;

                
                applicationObject = AutoCompletionService.Local.CreateApplication(this.Name, false, this.m_resolvedApplicationPool);
                this.CloneValuesTo(applicationObject);

                try
                {
                    applicationObject.CommitChanges();
                }
                catch (Exception exception)
                {
                    base.WriteError(exception, ErrorCategory.InvalidArgument, this);
                    base.SkipProcessCurrentRecord();
                }

                // Add the endpoints supported by the application
                // NOTE: AddServiceEndpoint should be called before app.Provision, because app.Provision will provision 
                // the default http endpoint if no endpoints have been explicitly added to the app.
                // Add the default net.tcp endpoint
                // NOTE: The default endpoint name is always "" (String.Empty).
                //serviceApplication.AddServiceEndpoint(string.Empty, SPIisWebServiceBindingType.NetTcp);
                applicationObject.AddServiceEndpoint(string.Empty, SPIisWebServiceBindingType.Http);
                applicationObject.AddServiceEndpoint("https", SPIisWebServiceBindingType.Https, "https");

                applicationObject.Update(true);

                applicationObject.Provision();

                AutoCompletionServiceApplicationProxy applicationProxy = (AutoCompletionServiceApplicationProxy)AutoCompletionService.Local.CreateProxy(this.Name, false, applicationObject, null);
                applicationProxy.Update(true);

                if (this.Default.IsPresent || forceDefault)
                {
                    applicationObject.RegisterAsDefaultApplication();
                }

                applicationProxy.Provision();

                return applicationObject;
            }

            base.SkipProcessCurrentRecord();
            
            return applicationObject;
        }

        protected override void InternalValidate()
        {
            base.InternalValidate();
            if (this.SPIisWebServiceApplicationPool != null)
            {
                this.m_resolvedApplicationPool = this.SPIisWebServiceApplicationPool.Read();
                if (null == this.m_resolvedApplicationPool)
                {
                    base.WriteError(new InvalidOperationException("ApplicationPoolNotFound"), ErrorCategory.InvalidArgument, this);
                    base.SkipProcessCurrentRecord();
                }
            }
        }

        #endregion
    }
}
